package org.cable.account.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.cable.account.config.RabbitMQConfig;
import org.cable.account.controller.request.AccountLoginRequest;
import org.cable.account.controller.request.AccountRegisterRequest;
import org.cable.account.model.AccountDO;
import org.cable.account.mapper.AccountMapper;
import org.cable.account.service.AccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.cable.account.service.NotifyService;
import org.cable.common.enums.AuthTypeEnum;
import org.cable.common.enums.BizCodeEnum;
import org.cable.common.enums.EventMessageType;
import org.cable.common.enums.SendCodeEnum;
import org.cable.common.model.EventMessage;
import org.cable.common.model.LoginUser;
import org.cable.common.util.CommonUtil;
import org.cable.common.util.IDUtil;
import org.cable.common.util.JWTUtil;
import org.cable.common.util.JsonData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hsj
 * @since 2023-10-25
 */
@Service
@Slf4j
public class AccountServiceImpl extends ServiceImpl<AccountMapper, AccountDO> implements AccountService {


    @Autowired
    private NotifyService notifyService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RabbitMQConfig rabbitMQConfig;

    /**
     * 免费流量包商品ID
     */
    private static final Long FREE_TRAFFIC_PRODUCT_ID = 1L;


    /**
     * 手机号验证码检查
     * 密码加密
     * 账号唯一检查
     * 插入数据库
     * 新注册用户福利发送
     *
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public JsonData register(AccountRegisterRequest request) {
        boolean checkCode = false;
        if (StringUtils.isNotBlank(request.getPhone())) {
            checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER, request.getPhone(), request.getCode());
        }
        if (!checkCode) {
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }

        AccountDO accountDO = new AccountDO();
        BeanUtils.copyProperties(request, accountDO);

        accountDO.setAuth(AuthTypeEnum.DEFAULT.name());

        /**设置密码 钥匙盐*/
        accountDO.setSecret("$1$" + CommonUtil.getStringNumRandom(8));

        /**md5加密盐和密码*/
        String cryptPwd = Md5Crypt.md5Crypt(request.getPwd().getBytes(StandardCharsets.UTF_8), accountDO.getSecret());

        accountDO.setPwd(cryptPwd);

        accountDO.setAccountNo(Long.valueOf(IDUtil.geneSnowFlakeID().toString()));

        save(accountDO);

        log.info("账户:{}注册成功", accountDO);

        /**用户注册成功,发放福利*/
        userRegisterInitTask(accountDO);

        return JsonData.buildSuccess();
    }

    /**
     * 用户初始化,发放福利：流量包
     *
     * @param accountDO
     */
    private void userRegisterInitTask(AccountDO accountDO) {
        EventMessage eventMessage  = EventMessage.builder()
                                         .messageId(IDUtil.geneSnowFlakeID().toString())
                                         .accountNo(accountDO.getAccountNo())
                                         .eventMessageType(EventMessageType.TRAFFIC_FREE_INIT.name())
                                         .bizId(FREE_TRAFFIC_PRODUCT_ID.toString())
                                         .build();


        //发送发放流量包消息
        rabbitTemplate.convertAndSend(rabbitMQConfig.getTrafficEventExchange(),
                                      rabbitMQConfig.getTrafficFreeInitRoutingKey(),eventMessage);




    }


    @Override
    public JsonData login(AccountLoginRequest request) {

        AccountDO accountDO = findByPhone(request.getPhone());

        if (null == accountDO) {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_UNREGISTER);
        }

        String md5Crypt = Md5Crypt.md5Crypt(request.getPwd().getBytes(StandardCharsets.UTF_8), accountDO.getSecret());
        if (!md5Crypt.equalsIgnoreCase(accountDO.getPwd())) {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
        }

        LoginUser loginUser = LoginUser.builder().build();
        BeanUtils.copyProperties(accountDO,loginUser);
        String token = JWTUtil.geneJsonWebTokne(loginUser);
        return JsonData.buildSuccess(token);
    }


    @Override
    public AccountDO findByPhone(String phone) {
        LambdaQueryWrapper<AccountDO> queryWrapper = new LambdaQueryWrapper<AccountDO>().eq(AccountDO::getPhone, phone);
        return this.baseMapper.selectOne(queryWrapper);
    }
}
